/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */

package com.ecarx.systemui.plugin.controller.hvac;

import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;

import com.ecarx.systemui.plugin.AppConstants;
import com.ecarx.systemui.plugin.controller.CarSignalController;
import com.ecarx.systemui.plugin.model.listener.SeatFuncNotifyViewListener;
import com.ecarx.systemui.plugin.utils.LogUtils;
import com.ecarx.systemui.plugin.utils.ThreadUtils;
import com.ecarx.xui.adaptapi.FunctionStatus;

public class SeatSignalController implements CarPropertyManager.CarPropertyEventCallback {

    private static final String TAG = "SeatHeatSignalControllerTag";

    private static SeatSignalController seatSignalController;

    private SeatSignalController() {
        doRegisterSignal();
    }

    public static synchronized SeatSignalController getInstance() {
        if (seatSignalController == null) {
            seatSignalController = new SeatSignalController();
        }
        return seatSignalController;
    }

    private SeatFuncNotifyViewListener seatLeftNotifyViewListener;
    private SeatFuncNotifyViewListener seatRightNotifyViewListener;

    public void setSeatLeftNotifyViewListener(
            SeatFuncNotifyViewListener seatFuncNotifyViewListener) {
        this.seatLeftNotifyViewListener = seatFuncNotifyViewListener;
    }

    public void setSeatRightNotifyViewListener(
            SeatFuncNotifyViewListener seatFuncNotifyViewListener) {
        this.seatRightNotifyViewListener = seatFuncNotifyViewListener;
    }

    //---------------------------主驾驶---------------------------------------
    //IHvacModule.HVAC_FUNC_SEAT_HEATING
    //IHvacModule.HVAC_FUNC_SEAT_Vent
    //IHvacModule.HVAC_FUNC_STEERING_WHEEL_HEAT
    private void doRegisterSignal() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            ThreadUtils.postDelayOnMain(100, this::doRegisterSignal);
            return;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.registerCallback(this,
                VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, CarPropertyManager.SENSOR_RATE_NORMAL);
        carPropertyManager.registerCallback(this,
                VehiclePropertyIds.HVAC_SEAT_VENTILATION, CarPropertyManager.SENSOR_RATE_NORMAL);
        carPropertyManager.registerCallback(this,
                VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT, CarPropertyManager.SENSOR_RATE_NORMAL);
    }

    private void doUnRegisterSignal() {
        boolean isOk = CarSignalController.checkSelf();
        if (isOk) {
            CarPropertyManager carPropertyManager =
                    CarSignalController.getInstance().getCarPropertyManager();
            carPropertyManager.unregisterCallback(this);
        }
    }

    public boolean isSupportDriverSeatHeat() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 1);
    }

    public boolean isSupportDriverSeatVent() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 1);
    }

    public boolean isSupportWheelHeat() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT, 0);
    }

    public int getDriverSeatVentValue() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 1);
    }

    public int getDriverSeatHeatValue() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 1);
    }

    public int getWheelHeatValue() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT, 0);
    }


    public void adjustWheelHeat() {
        int wheelHeatValue = getWheelHeatValue();
        LogUtils.d(TAG, "adjustWheelHeat currentWheelHeatValue:" + wheelHeatValue);
        if (wheelHeatValue == 255) {
            return;
        }
        int nextValue = wheelHeatValue;
        switch (wheelHeatValue) {
            case AppConstants.HEAT_LEVEL_0:
                nextValue = AppConstants.HEAT_LEVEL_3;
                break;
            case AppConstants.HEAT_LEVEL_1:
                nextValue = AppConstants.HEAT_LEVEL_2;
                break;
            case AppConstants.HEAT_LEVEL_2:
                nextValue = AppConstants.HEAT_LEVEL_1;
                break;
            case AppConstants.HEAT_LEVEL_3:
                nextValue = AppConstants.HEAT_LEVEL_0;
                break;
        }
        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT, 0, nextValue);
        LogUtils.d(TAG, "adjustWheelHeat nextValue:" + nextValue);
    }

    public void adjustDriverSeatHeat() {
        int driverSeatHeatValue = getDriverSeatHeatValue();
        LogUtils.d(TAG, "adjustDriverSeatHeat driverSeatHeatValue:" + driverSeatHeatValue);
        if (driverSeatHeatValue == 255) {
            return;
        }
        //OFF -> HI -> MID -> LO -> OFF
        int nextValue = driverSeatHeatValue;
        switch (driverSeatHeatValue) {
            case AppConstants.HEAT_LEVEL_0:
                nextValue = AppConstants.HEAT_LEVEL_3;
                break;
            case AppConstants.HEAT_LEVEL_1:
                nextValue = AppConstants.HEAT_LEVEL_2;
                break;
            case AppConstants.HEAT_LEVEL_2:
                nextValue = AppConstants.HEAT_LEVEL_1;
                break;
            case AppConstants.HEAT_LEVEL_3:
                nextValue = AppConstants.HEAT_LEVEL_0;
                break;
        }
        //关闭主驾驶通风
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        if (isSupportDriverSeatVent()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 1, AppConstants.HEAT_LEVEL_0);
        }
        if (isSupportPassengerSeatHeat()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 1, nextValue);
        }

        LogUtils.d(TAG, "adjustDriverSeatHeat nextValue:" + nextValue);
    }

    public void adjustDriverSeatVent() {
        int driverSeatVentValue = getDriverSeatVentValue();
        LogUtils.d(TAG, "adjustDriverSeatVent driverSeatVentValue:" + driverSeatVentValue);
        if (driverSeatVentValue == 255) {
            return;
        }
        //OFF -> HI -> MID -> LO -> OFF
        int nextValue = driverSeatVentValue;
        switch (driverSeatVentValue) {
            case AppConstants.HEAT_LEVEL_0:
                nextValue = AppConstants.HEAT_LEVEL_3;
                break;
            case AppConstants.HEAT_LEVEL_1:
                nextValue = AppConstants.HEAT_LEVEL_2;
                break;
            case AppConstants.HEAT_LEVEL_2:
                nextValue = AppConstants.HEAT_LEVEL_1;
                break;
            case AppConstants.HEAT_LEVEL_3:
                nextValue = AppConstants.HEAT_LEVEL_0;
                break;
        }

        //关闭主驾驶加热
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        if (isSupportDriverSeatHeat()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 1, AppConstants.HEAT_LEVEL_0);
        }
        if (isSupportPassengerSeatVent()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 1, nextValue);
        }

        LogUtils.d(TAG, "adjustDriverSeatVent nextValue:" + nextValue);
    }


    //---------------------------副驾驶---------------------------------------

    public void adjustPassengerSeatHeat() {
        int passengerSeatHeatValue = getPassengerSeatHeatValue();
        LogUtils.d(TAG, "adjustPassengerSeatHeat passengerSeatHeatValue:" + passengerSeatHeatValue);
        if (passengerSeatHeatValue == 255) {
            return;
        }
        int nextValue = passengerSeatHeatValue;
        switch (passengerSeatHeatValue) {
            case AppConstants.HEAT_LEVEL_0:
                nextValue = AppConstants.HEAT_LEVEL_3;
                break;
            case AppConstants.HEAT_LEVEL_1:
                nextValue = AppConstants.HEAT_LEVEL_2;
                break;
            case AppConstants.HEAT_LEVEL_2:
                nextValue = AppConstants.HEAT_LEVEL_1;
                break;
            case AppConstants.HEAT_LEVEL_3:
                nextValue = AppConstants.HEAT_LEVEL_0;
                break;
        }

        //关闭座椅通风
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        if (isSupportPassengerSeatVent()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 4, AppConstants.HEAT_LEVEL_0);
        }
        if (isSupportPassengerSeatHeat()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 4, nextValue);
        }

        LogUtils.d(TAG, "adjustPassengerSeatHeat nextValue:" + nextValue);
    }

    public void adjustPassengerSeatVent() {
        int passengerSeatVentValue = getPassengerSeatVentValue();
        LogUtils.d(TAG, "adjustPassengerSeatVent passengerSeatVentValue:" + passengerSeatVentValue);
        if (passengerSeatVentValue == 255) {
            return;
        }
        int nextValue = passengerSeatVentValue;
        //OFF -> HI -> MID -> LO -> OFF
        switch (passengerSeatVentValue) {
            case AppConstants.HEAT_LEVEL_0:
                nextValue = AppConstants.HEAT_LEVEL_3;
                break;
            case AppConstants.HEAT_LEVEL_1:
                nextValue = AppConstants.HEAT_LEVEL_2;
                break;
            case AppConstants.HEAT_LEVEL_2:
                nextValue = AppConstants.HEAT_LEVEL_1;
                break;
            case AppConstants.HEAT_LEVEL_3:
                nextValue = AppConstants.HEAT_LEVEL_0;
                break;
        }

        //关闭座椅加热
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        if (isSupportPassengerSeatHeat()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 4, AppConstants.HEAT_LEVEL_0);
        }
        if (isSupportPassengerSeatVent()) {
            carPropertyManager.setIntProperty(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 4, nextValue);
        }

        LogUtils.d(TAG, "adjustPassengerSeatVent nextValue:" + nextValue);
    }

    public boolean isSupportPassengerSeatHeat() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 4);
    }

    public boolean isSupportPassengerSeatVent() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 4);
    }

    public int getPassengerSeatVentValue() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_SEAT_VENTILATION, 4);
    }

    public int getPassengerSeatHeatValue() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_SEAT_TEMPERATURE, 4);
    }

    @Override
    public void onChangeEvent(CarPropertyValue carPropertyValue) {
        if (seatLeftNotifyViewListener == null || seatRightNotifyViewListener == null) {
            return;
        }
        int propertyId = carPropertyValue.getPropertyId();
        int areaId = carPropertyValue.getAreaId();
        int status = carPropertyValue.getStatus();
        FunctionStatus functionStatus = CarSignalController.toFunctionStatus(status);
        Object value = carPropertyValue.getValue();
        switch (propertyId) {
            case VehiclePropertyIds.HVAC_SEAT_TEMPERATURE:
                int seatHeatValue = (int) value;
                if (1 == areaId) {
                    seatLeftNotifyViewListener.notifyDriverSeatHeatChanged(
                            seatHeatValue, functionStatus);
                } else if (4 == areaId) {
                    seatRightNotifyViewListener.notifyPassengerSeatHeatChanged(
                            seatHeatValue, functionStatus);
                }
                break;
            case VehiclePropertyIds.HVAC_SEAT_VENTILATION:
                int seatVentValue = (int) value;
                if (1 == areaId) {
                    seatLeftNotifyViewListener.notifyDriverSeatVentChanged(
                            seatVentValue, functionStatus);
                } else if (4 == areaId) {
                    seatRightNotifyViewListener.notifyPassengerSeatVentChanged(
                            seatVentValue, functionStatus);
                }
                break;
            case VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT:
                int wheelHeatValue = (int) value;
                seatLeftNotifyViewListener.notifyWheelHeatChanged(wheelHeatValue, functionStatus);
                break;
        }

    }

    @Override
    public void onErrorEvent(int i, int i1) {

    }
}
